/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

/**
 * Factory hook that allows for custom modification of an application context's
 * bean definitions, adapting the bean property values of the context's underlying
 * bean factory.
 *
 * 工厂钩子（Factory Hook），允许对应用上下文中的 BeanDefinition 进行自定义修改，
 * 调整上下文底层 BeanFactory 中 Bean 的属性值。
 *
 * <p>Useful for custom config files targeted at system administrators that
 * override bean properties configured in the application context. See
 * {@link PropertyResourceConfigurer} and its concrete implementations for
 * out-of-the-box solutions that address such configuration needs.
 *
 * 对系统管理员定制的配置文件特别有用，可以覆盖应用上下文中已经配置的 Bean 属性。
 * 参见 {@link PropertyResourceConfigurer} 及其具体实现，提供开箱即用的配置方案。
 *
 * <p>A {@code BeanFactoryPostProcessor} may interact with and modify bean
 * definitions, but never bean instances. Doing so may cause premature bean
 * instantiation, violating the container and causing unintended side-effects.
 * If bean instance interaction is required, consider implementing
 * {@link BeanPostProcessor} instead.
 *
 * BeanFactoryPostProcessor 可以操作和修改 BeanDefinition，但不能操作 Bean 实例。
 * 如果操作实例，会导致 Bean 提前实例化，破坏容器生命周期并产生副作用。
 * 如果确实需要操作 Bean 实例，应使用 {@link BeanPostProcessor}。
 *
 * <h3>Registration</h3>
 * <p>An {@code ApplicationContext} auto-detects {@code BeanFactoryPostProcessor}
 * beans in its bean definitions and applies them before any other beans get created.
 * A {@code BeanFactoryPostProcessor} may also be registered programmatically
 * with a {@code ConfigurableApplicationContext}.
 *
 * 注册机制：
 * ApplicationContext 会自动检测 BeanDefinition 中的 BeanFactoryPostProcessor，
 * 并在其他 Bean 创建前执行。
 * 也可以通过 ConfigurableApplicationContext 编程方式注册。
 *
 * <h3>Ordering</h3>
 * <p>{@code BeanFactoryPostProcessor} beans that are autodetected in an
 * {@code ApplicationContext} will be ordered according to
 * {@link org.springframework.core.PriorityOrdered} and
 * {@link org.springframework.core.Ordered} semantics. In contrast,
 * {@code BeanFactoryPostProcessor} beans that are registered programmatically
 * with a {@code ConfigurableApplicationContext} will be applied in the order of
 * registration; any ordering semantics expressed through implementing the
 * {@code PriorityOrdered} or {@code Ordered} interface will be ignored for
 * programmatically registered post-processors. Furthermore, the
 * {@link org.springframework.core.annotation.Order @Order} annotation is not
 * taken into account for {@code BeanFactoryPostProcessor} beans.
 *
 * 顺序处理：
 * - 自动检测的 BeanFactoryPostProcessor 会按照 PriorityOrdered 或 Ordered 接口排序。
 * - 编程注册的 BeanFactoryPostProcessor 按注册顺序执行，不受 PriorityOrdered / Ordered 接口影响。
 * - @Order 注解对 BeanFactoryPostProcessor 无效。
 *
 * 核心功能：
 * 1. 提供 Bean 实例化前修改 BeanDefinition 的能力。
 * 2. 支撑外部配置文件、系统管理员定制等动态属性修改。
 *
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 06.07.2003
 * @see BeanPostProcessor
 * @see PropertyResourceConfigurer
 */
@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 *
	 * 在应用上下文标准初始化后修改内部 BeanFactory。
	 * 所有 BeanDefinition 已经加载，但 Bean 实例尚未创建。
	 * 可覆盖或新增属性，即使是提前初始化的 Bean 也可以修改。
	 *
	 * 核心逻辑：
	 * 1. 容器刷新 Refresh 方法会调用 PostProcessorRegistrationDelegate。
	 * 2. 遍历所有 BeanFactoryPostProcessor 实例。
	 * 3. 调用 postProcessBeanFactory(beanFactory)。
	 * 4. 用户可通过 beanFactory.getBeanDefinition(name) 修改属性或注册依赖。
	 *
	 * 框架作用：
	 * - 提供 Bean 实例化前扩展点，支撑动态配置。
	 * - 被 ConfigurationClassPostProcessor、PropertySourcesPlaceholderConfigurer 等实现。
	 *
	 * @param beanFactory the bean factory used by the application context
	 *                    应用上下文使用的 BeanFactory
	 * @throws org.springframework.beans.BeansException in case of errors
	 *                                                出现错误时抛出 BeansException
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
